#ifndef _LINUX_FS_H
#define _LINUX_FS_H

#include <linux/types.h>
#include <linux/radix-tree.h>
#include <linux/spinlock.h>
#include <linux/list.h>
#include <linux/uio.h>
#include <linux/aio.h>
#include <linux/dcache.h>
#include <linux/path.h>
#include <linux/namei.h>
#include <linux/mount.h>
#include <linux/mm_types.h>

#define RW_MASK		1
#define RWA_MASK	2
#define READ 0
#define WRITE 1
#define READA 2		/* read-ahead  - don't block if no resources */
#define SWRITE 3	/* for ll_rw_block() - wait for buffer lock */

typedef int (get_block_t)(struct inode *inode, sector_t iblock,
			struct buffer_head *bh_result, int create);

#define BLOCK_SIZE_BITS 10
#define BLOCK_SIZE (1<<BLOCK_SIZE_BITS)

#define MS_RDONLY	 1	/* Mount read-only */
#define MS_NOSUID	 2	/* Ignore suid and sgid bits */
#define MS_NODEV	 4	/* Disallow access to device special files */
#define MS_NOEXEC	 8	/* Disallow program execution */
#define MS_SYNCHRONOUS	16	/* Writes are synced at once */
#define MS_REMOUNT	32	/* Alter flags of a mounted FS */
#define MS_MANDLOCK	64	/* Allow mandatory locks on an FS */
#define MS_DIRSYNC	128	/* Directory modifications are synchronous */
#define MS_NOATIME	1024	/* Do not update access times. */
#define MS_NODIRATIME	2048	/* Do not update directory access times */
#define MS_BIND		4096
#define MS_MOVE		8192
#define MS_REC		16384
#define MS_VERBOSE	32768	/* War is peace. Verbosity is silence.
				   MS_VERBOSE is deprecated. */
#define MS_SILENT	32768
#define MS_POSIXACL	(1<<16)	/* VFS does not apply the umask */
#define MS_UNBINDABLE	(1<<17)	/* change to unbindable */
#define MS_PRIVATE	(1<<18)	/* change to private */
#define MS_SLAVE	(1<<19)	/* change to slave */
#define MS_SHARED	(1<<20)	/* change to shared */
#define MS_RELATIME	(1<<21)	/* Update atime relative to mtime/ctime. */
#define MS_KERNMOUNT	(1<<22) /* this is a kern_mount call */
#define MS_I_VERSION	(1<<23) /* Update inode I_version field */
#define MS_STRICTATIME	(1<<24) /* Always perform atime updates */
#define MS_ACTIVE	(1<<30)
#define MS_NOUSER	(1<<31)

#define BDEVNAME_SIZE	32	/* Largest string for a blockdev identifier */

#define	MAX_NON_LFS	((1UL<<31) - 1)

typedef struct {
	size_t written;
	size_t count;
	union {
		char *buf;
		void *data;
	} arg;
	int error;
} read_descriptor_t;

typedef int (*read_actor_t)(read_descriptor_t *, struct page *,
		unsigned long, unsigned long);

typedef int (*filldir_t)(void *, const char *, int, loff_t, u64, unsigned);

struct dirent {
	unsigned char d_name[32];
};

struct dirents {
	int num;
	struct dirent *dirent;
};

struct file_ra_state {
	pgoff_t start;			/* where readahead started */
	unsigned int size;		/* # of readahead pages */
	unsigned int async_size;	/* do asynchronous readahead when
					   there are only # of pages ahead */

	unsigned int ra_pages;		/* Maximum readahead window */
	unsigned int mmap_miss;		/* Cache miss stat for mmap accesses */
	loff_t prev_pos;		/* Cache last read() position */
};

struct file {
	/*
	 * fu_list becomes invalid after file_free is called and queued via
	 * fu_rcuhead for RCU freeing
	 */
	// union {
		// struct list_head	fu_list;
		// struct rcu_head 	fu_rcuhead;
	// } f_u;
	struct path		f_path;
#define f_dentry	f_path.dentry
#define f_vfsmnt	f_path.mnt
	const struct file_operations	*f_op;
	// spinlock_t		f_lock;  /* f_ep_links, f_flags, no IRQ */
	// atomic_long_t		f_count;
	unsigned int 		f_flags;
	// fmode_t			f_mode;
	loff_t			f_pos;
	// struct fown_struct	f_owner;
	// const struct cred	*f_cred;
	struct file_ra_state	f_ra;

	u64			f_version;
// #ifdef CONFIG_SECURITY
// 	void			*f_security;
// #endif
	/* needed for tty driver, and maybe others */
	void			*private_data;

// #ifdef CONFIG_EPOLL
// 	/* Used by fs/eventpoll.c to link all the hooks to this file */
// 	struct list_head	f_ep_links;
// #endif /* #ifdef CONFIG_EPOLL */
	struct address_space	*f_mapping;
// #ifdef CONFIG_DEBUG_WRITECOUNT
// 	unsigned long f_mnt_write_state;
// #endif
};

struct super_operations {
   	struct inode *(*alloc_inode)(struct super_block *sb);
// 	void (*destroy_inode)(struct inode *);

//    	void (*dirty_inode) (struct inode *);
	int (*write_inode) (struct inode *, int);
// 	void (*drop_inode) (struct inode *);
// 	void (*delete_inode) (struct inode *);
// 	void (*put_super) (struct super_block *);
// 	void (*write_super) (struct super_block *);
// 	int (*sync_fs)(struct super_block *sb, int wait);
// 	int (*freeze_fs) (struct super_block *);
// 	int (*unfreeze_fs) (struct super_block *);
// 	int (*statfs) (struct dentry *, struct kstatfs *);
// 	int (*remount_fs) (struct super_block *, int *, char *);
// 	void (*clear_inode) (struct inode *);
// 	void (*umount_begin) (struct super_block *);

// 	int (*show_options)(struct seq_file *, struct vfsmount *);
// 	int (*show_stats)(struct seq_file *, struct vfsmount *);
// #ifdef CONFIG_QUOTA
// 	ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t);
// 	ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t);
// #endif
// 	int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t);
};

struct super_block {
	struct list_head	s_list;		/* Keep this first */
	dev_t			s_dev;		/* search index; _not_ kdev_t */
	unsigned long		s_blocksize;
	unsigned char		s_blocksize_bits;
	unsigned char		s_dirt;
	loff_t			s_maxbytes;	/* Max file size */
	struct file_system_type	*s_type;
	const struct super_operations	*s_op;
	// const struct dquot_operations	*dq_op;
	// const struct quotactl_ops	*s_qcop;
	// const struct export_operations *s_export_op;
	unsigned long		s_flags;
	unsigned long		s_magic;
	struct dentry		*s_root;
	// struct rw_semaphore	s_umount;
	// struct mutex		s_lock;
	int			s_count;
	int			s_need_sync;
	atomic_t		s_active;
// #ifdef CONFIG_SECURITY
// 	void                    *s_security;
// #endif
	// struct xattr_handler	**s_xattr;

	struct list_head	s_inodes;	/* all inodes */
	// struct hlist_head	s_anon;		/* anonymous dentries for (nfs) exporting */
	struct list_head	s_files;
	/* s_dentry_lru and s_nr_dentry_unused are protected by dcache_lock */
	struct list_head	s_dentry_lru;	/* unused dentry lru */
	int			s_nr_dentry_unused;	/* # of dentry on lru */

	struct block_device	*s_bdev;
	// struct backing_dev_info *s_bdi;
	// struct mtd_info		*s_mtd;
	struct list_head	s_instances;
	// struct quota_info	s_dquot;	/* Diskquota specific options */

	int			s_frozen;
	// wait_queue_head_t	s_wait_unfrozen;

	char s_id[32];				/* Informational name */

	void 			*s_fs_info;	/* Filesystem private info */
	// fmode_t			s_mode;

	/*
	 * The next field is for VFS *only*. No filesystems have any business
	 * even looking at it. You had been warned.
	 */
	// struct mutex s_vfs_rename_mutex;	/* Kludge */

	/* Granularity of c/m/atime in ns.
	   Cannot be worse than a second */
	u32		   s_time_gran;

	/*
	 * Filesystem subtype.  If non-empty the filesystem type field
	 * in /proc/mounts will be "type.subtype"
	 */
	char *s_subtype;

	/*
	 * Saved mount options for lazy filesystems using
	 * generic_show_options()
	 */
	char *s_options;
};

struct file_operations {
	// struct module *owner;
	// loff_t (*llseek) (struct file *, loff_t, int);
	ssize_t (*read) (struct file *, char *, size_t, loff_t *);
	ssize_t (*write) (struct file *, const char *, size_t, loff_t *);
	ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
	ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
	int (*readdir) (struct file *, void *, filldir_t);
	// unsigned int (*poll) (struct file *, struct poll_table_struct *);
	// int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
	// long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
	// long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
	int (*mmap) (struct file *, struct vm_area_struct *);
	int (*open) (struct inode *, struct file *);
	// int (*flush) (struct file *, fl_owner_t id);
	// int (*release) (struct inode *, struct file *);
	// int (*fsync) (struct file *, struct dentry *, int datasync);
	// int (*aio_fsync) (struct kiocb *, int datasync);
	// int (*fasync) (int, struct file *, int);
	// int (*lock) (struct file *, int, struct file_lock *);
	// ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
	// unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
	// int (*check_flags)(int);
	// int (*flock) (struct file *, int, struct file_lock *);
	// ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
	// ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
	// int (*setlease)(struct file *, long, struct file_lock **);
};

struct inode_operations {
	int (*create) (struct inode *,struct dentry *,int, struct nameidata *);
	struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *);
	// int (*link) (struct dentry *,struct inode *,struct dentry *);
	// int (*unlink) (struct inode *,struct dentry *);
	// int (*symlink) (struct inode *,struct dentry *,const char *);
	int (*mkdir) (struct inode *,struct dentry *,int);
	int (*rmdir) (struct inode *,struct dentry *);
	int (*mknod) (struct inode *,struct dentry *,int,dev_t);
	// int (*rename) (struct inode *, struct dentry *,
	// 		struct inode *, struct dentry *);
	// int (*readlink) (struct dentry *, char *,int);
	// void * (*follow_link) (struct dentry *, struct nameidata *);
	// void (*put_link) (struct dentry *, struct nameidata *, void *);
	// void (*truncate) (struct inode *);
	// int (*permission) (struct inode *, int);
	// int (*check_acl)(struct inode *, int);
	// int (*setattr) (struct dentry *, struct iattr *);
	// int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
	// int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
	// ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
	// ssize_t (*listxattr) (struct dentry *, char *, size_t);
	// int (*removexattr) (struct dentry *, const char *);
	// void (*truncate_range)(struct inode *, loff_t, loff_t);
	// long (*fallocate)(struct inode *inode, int mode, loff_t offset,
	// 		  loff_t len);
	// int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start,
	// 	      u64 len);
};

struct address_space_operations {
	// int (*writepage)(struct page *page, struct writeback_control *wbc);
	int (*readpage)(struct file *, struct page *);
	// void (*sync_page)(struct page *);

	// /* Write back some dirty pages from this mapping. */
	// int (*writepages)(struct address_space *, struct writeback_control *);

	// /* Set a page dirty.  Return true if this dirtied it */
	// int (*set_page_dirty)(struct page *page);

	// int (*readpages)(struct file *filp, struct address_space *mapping,
	// 		struct list_head *pages, unsigned nr_pages);

	int (*write_begin)(struct file *, struct address_space *mapping,
				loff_t pos, unsigned len, unsigned flags,
				struct page **pagep, void **fsdata);
	int (*write_end)(struct file *, struct address_space *mapping,
				loff_t pos, unsigned len, unsigned copied,
				struct page *page, void *fsdata);

	// /* Unfortunately this kludge is needed for FIBMAP. Don't use it */
	// sector_t (*bmap)(struct address_space *, sector_t);
	// void (*invalidatepage) (struct page *, unsigned long);
	// int (*releasepage) (struct page *, gfp_t);
	// ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
	// 		loff_t offset, unsigned long nr_segs);
	// int (*get_xip_mem)(struct address_space *, pgoff_t, int,
	// 					void **, unsigned long *);
	// /* migrate the contents of a page to the specified target */
	// int (*migratepage) (struct address_space *,
	// 		struct page *, struct page *);
	// int (*launder_page) (struct page *);
	// int (*is_partially_uptodate) (struct page *, read_descriptor_t *,
	// 				unsigned long);
	// int (*error_remove_page)(struct address_space *, struct page *);
};

struct address_space {
	struct inode		*host;		/* owner: inode, block_device */
	struct radix_tree_root	page_tree;	/* radix tree of all pages */
	spinlock_t		tree_lock;	/* and lock protecting it */
	unsigned int		i_mmap_writable;/* count VM_SHARED mappings */
	// struct prio_tree_root	i_mmap;		/* tree of private and shared mappings */
	struct list_head	i_mmap_nonlinear;/*list VM_NONLINEAR mappings */
	spinlock_t		i_mmap_lock;	/* protect tree, count, list */
	unsigned int		truncate_count;	/* Cover race condition with truncate */
	unsigned long		nrpages;	/* number of total pages */
	pgoff_t			writeback_index;/* writeback starts here */
	const struct address_space_operations *a_ops;	/* methods */
	unsigned long		flags;		/* error bits/gfp mask */
	// struct backing_dev_info *backing_dev_info; /* device readahead, etc */
	spinlock_t		private_lock;	/* for use by the address_space */
	struct list_head	private_list;	/* ditto */
	struct address_space	*assoc_mapping;	/* ditto */
};

struct block_device {
	dev_t			bd_dev;  /* not a kdev_t - it's a search key */
	struct inode *		bd_inode;	/* will die */
	struct super_block *	bd_super;
	int			bd_openers;
	// struct mutex		bd_mutex;	/* open/close mutex */
	struct list_head	bd_inodes;
	void *			bd_holder;
	int			bd_holders;
// #ifdef CONFIG_SYSFS
// 	struct list_head	bd_holder_list;
// #endif
	struct block_device *	bd_contains;
	unsigned		bd_block_size;
	// struct hd_struct *	bd_part;
	/* number of times partitions within this device have been opened. */
	unsigned		bd_part_count;
	int			bd_invalidated;
	// struct gendisk *	bd_disk;
	struct list_head	bd_list;
	/*
	 * Private data.  You must have bd_claim'ed the block_device
	 * to use this.  NOTE:  bd_claim allows an owner to claim
	 * the same device multiple times, the owner must take special
	 * care to not mess up bd_private for that case.
	 */
	unsigned long		bd_private;

	/* The counter of freeze processes */
	int			bd_fsfreeze_count;
	/* Mutex for freeze */
	// struct mutex		bd_fsfreeze_mutex;
};

struct inode {
	struct hlist_node	i_hash;
	struct list_head	i_list;		/* backing dev IO list */
	struct list_head	i_sb_list;
	struct list_head	i_dentry;
	unsigned long		i_ino;
	atomic_t		i_count;
	unsigned int		i_nlink;
	uid_t			i_uid;
	gid_t			i_gid;
	dev_t			i_rdev;
	u64			i_version;
	loff_t			i_size;
// #ifdef __NEED_I_SIZE_ORDERED
// 	seqcount_t		i_size_seqcount;
// #endif
	// struct timespec		i_atime;
	// struct timespec		i_mtime;
	// struct timespec		i_ctime;
	blkcnt_t		i_blocks;
	unsigned int		i_blkbits;
	unsigned short          i_bytes;
	umode_t			i_mode;
	// spinlock_t		i_lock;	/* i_blocks, i_bytes, maybe i_size */
	// struct mutex		i_mutex;
	// struct rw_semaphore	i_alloc_sem;
	const struct inode_operations	*i_op;
	const struct file_operations	*i_fop;	/* former ->i_op->default_file_ops */
	struct super_block	*i_sb;
	// struct file_lock	*i_flock;
	struct address_space	*i_mapping;
	struct address_space	i_data;
// #ifdef CONFIG_QUOTA
// 	struct dquot		*i_dquot[MAXQUOTAS];
// #endif
	struct list_head	i_devices;
	// union {
	// 	struct pipe_inode_info	*i_pipe;
	// 	struct block_device	*i_bdev;
	// 	struct cdev		*i_cdev;
	// };

	__u32			i_generation;

// #ifdef CONFIG_FSNOTIFY
// 	__u32			i_fsnotify_mask; /* all events this inode cares about */
// 	struct hlist_head	i_fsnotify_mark_entries; /* fsnotify mark entries */
// #endif

// #ifdef CONFIG_INOTIFY
// 	struct list_head	inotify_watches; /* watches on this inode */
// 	struct mutex		inotify_mutex;	/* protects the watches list */
// #endif

	unsigned long		i_state;
	unsigned long		dirtied_when;	/* jiffies of first dirtying */

	unsigned int		i_flags;

	atomic_t		i_writecount;
// #ifdef CONFIG_SECURITY
// 	void			*i_security;
// #endif
// #ifdef CONFIG_FS_POSIX_ACL
// 	struct posix_acl	*i_acl;
// 	struct posix_acl	*i_default_acl;
// #endif
	void			*i_private; /* fs or device private pointer */
};

struct file_system_type {
	const char *name;
	int fs_flags;
	int (*get_sb) (struct file_system_type *, int,
		       const char *, void *, struct vfsmount *);
	void (*kill_sb) (struct super_block *);
	// struct module *owner;
	struct file_system_type * next;
	struct list_head fs_supers;

	// struct lock_class_key s_lock_key;
	// struct lock_class_key s_umount_key;

	// struct lock_class_key i_lock_key;
	// struct lock_class_key i_mutex_key;
	// struct lock_class_key i_mutex_dir_key;
	// struct lock_class_key i_alloc_sem_key;
};

static inline loff_t i_size_read(const struct inode *inode)
{
// #if BITS_PER_LONG==32 && defined(CONFIG_SMP)
// 	loff_t i_size;
// 	unsigned int seq;

// 	do {
// 		seq = read_seqcount_begin(&inode->i_size_seqcount);
// 		i_size = inode->i_size;
// 	} while (read_seqcount_retry(&inode->i_size_seqcount, seq));
// 	return i_size;
// #elif BITS_PER_LONG==32 && defined(CONFIG_PREEMPT)
	// loff_t i_size;

	// preempt_disable();
	// i_size = inode->i_size;
	// preempt_enable();
	// return i_size;
// #else
	return inode->i_size;
// #endif
}

static inline void i_size_write(struct inode *inode, loff_t i_size)
{
// #if BITS_PER_LONG==32 && defined(CONFIG_SMP)
// 	write_seqcount_begin(&inode->i_size_seqcount);
// 	inode->i_size = i_size;
// 	write_seqcount_end(&inode->i_size_seqcount);
// #elif BITS_PER_LONG==32 && defined(CONFIG_PREEMPT)
// 	preempt_disable();
// 	inode->i_size = i_size;
// 	preempt_enable();
// #else
	inode->i_size = i_size;
// #endif
}

extern const struct file_operations generic_ro_fops;
extern int generic_file_readonly_mmap(struct file *, struct vm_area_struct *);

struct iov_iter {
	const struct iovec *iov;
	unsigned long nr_segs;
	size_t iov_offset;
	size_t count;
};

static inline void iov_iter_init(struct iov_iter *i,
			const struct iovec *iov, unsigned long nr_segs,
			size_t count, size_t written)
{
	i->iov = iov;
	i->nr_segs = nr_segs;
	i->iov_offset = 0;
	i->count = count + written;

	iov_iter_advance(i, written);
}

static inline size_t iov_iter_count(struct iov_iter *i)
{
	return i->count;
}

extern int simple_readpage(struct file *file, struct page *page);
extern int simple_prepare_write(struct file *file, struct page *page,
			unsigned offset, unsigned to);
extern int simple_write_begin(struct file *file, struct address_space *mapping,
			loff_t pos, unsigned len, unsigned flags,
			struct page **pagep, void **fsdata);
extern int simple_write_end(struct file *file, struct address_space *mapping,
			loff_t pos, unsigned len, unsigned copied,
			struct page *page, void *fsdata);
extern struct dentry *simple_lookup(struct inode *, struct dentry *, struct nameidata *);

extern ssize_t do_sync_read(struct file *filp, char *buf, size_t len, loff_t *ppos);
extern ssize_t do_sync_write(struct file *filp, const char *buf, size_t len, loff_t *ppos);

extern ssize_t generic_file_aio_read(struct kiocb *, const struct iovec *, unsigned long, loff_t);
extern ssize_t generic_file_aio_write(struct kiocb *, const struct iovec *, unsigned long, loff_t);
extern int generic_file_open(struct inode * inode, struct file * filp);

extern const struct file_operations simple_dir_operations;

// #define MAX_LFS_FILESIZE	(((u64)PAGE_CACHE_SIZE << (BITS_PER_LONG-1))-1) 
#define MAX_LFS_FILESIZE	(((u64)(1 << 12) << (BITS_PER_LONG-1))-1) 

#define DT_UNKNOWN	0
#define DT_FIFO		1
#define DT_CHR		2
#define DT_DIR		4
#define DT_BLK		6
#define DT_REG		8
#define DT_LNK		10
#define DT_SOCK		12
#define DT_WHT		14

static inline ino_t parent_ino(struct dentry *dentry)
{
	ino_t res;

	// spin_lock(&dentry->d_lock);
	res = dentry->d_parent->d_inode->i_ino;
	// spin_unlock(&dentry->d_lock);
	return res;
}

#define I_DIRTY_SYNC		1
#define I_DIRTY_DATASYNC	2
#define I_DIRTY_PAGES		4
#define I_NEW			8
#define I_WILL_FREE		16
#define I_FREEING		32
#define I_CLEAR			64
#define __I_LOCK		7
#define I_LOCK			(1 << __I_LOCK)
#define __I_SYNC		8
#define I_SYNC			(1 << __I_SYNC)

#define I_DIRTY (I_DIRTY_SYNC | I_DIRTY_DATASYNC | I_DIRTY_PAGES)

/* Inode flags - they have nothing to superblock flags now */

#define S_SYNC		1	/* Writes are synced at once */
#define S_NOATIME	2	/* Do not update access times */
#define S_APPEND	4	/* Append-only file */
#define S_IMMUTABLE	8	/* Immutable file */
#define S_DEAD		16	/* removed, but still open directory */
#define S_NOQUOTA	32	/* Inode is not counted to quota */
#define S_DIRSYNC	64	/* Directory modifications are synchronous */
#define S_NOCMTIME	128	/* Do not update file c/mtime */
#define S_SWAPFILE	256	/* Do not truncate: swapon got its bmaps */
#define S_PRIVATE	512	/* Inode is fs-internal */

/*
 * Inode flags (FS_IOC_GETFLAGS / FS_IOC_SETFLAGS)
 */
#define	FS_SECRM_FL			0x00000001 /* Secure deletion */
#define	FS_UNRM_FL			0x00000002 /* Undelete */
#define	FS_COMPR_FL			0x00000004 /* Compress file */
#define FS_SYNC_FL			0x00000008 /* Synchronous updates */
#define FS_IMMUTABLE_FL			0x00000010 /* Immutable file */
#define FS_APPEND_FL			0x00000020 /* writes to file may only append */
#define FS_NODUMP_FL			0x00000040 /* do not dump file */
#define FS_NOATIME_FL			0x00000080 /* do not update atime */
/* Reserved for compression usage... */
#define FS_DIRTY_FL			0x00000100
#define FS_COMPRBLK_FL			0x00000200 /* One or more compressed clusters */
#define FS_NOCOMP_FL			0x00000400 /* Don't compress */
#define FS_ECOMPR_FL			0x00000800 /* Compression error */
/* End compression flags --- maybe not all used */
#define FS_BTREE_FL			0x00001000 /* btree format dir */
#define FS_INDEX_FL			0x00001000 /* hash-indexed directory */
#define FS_IMAGIC_FL			0x00002000 /* AFS directory */
#define FS_JOURNAL_DATA_FL		0x00004000 /* Reserved for ext3 */
#define FS_NOTAIL_FL			0x00008000 /* file tail should not be merged */
#define FS_DIRSYNC_FL			0x00010000 /* dirsync behaviour (directories only) */
#define FS_TOPDIR_FL			0x00020000 /* Top of directory hierarchies*/
#define FS_EXTENT_FL			0x00080000 /* Extents */
#define FS_DIRECTIO_FL			0x00100000 /* Use direct i/o */
#define FS_RESERVED_FL			0x80000000 /* reserved for ext2 lib */

#define FS_FL_USER_VISIBLE		0x0003DFFF /* User visible flags */
#define FS_FL_USER_MODIFIABLE		0x000380FF /* User modifiable flags */


#define SYNC_FILE_RANGE_WAIT_BEFORE	1
#define SYNC_FILE_RANGE_WRITE		2
#define SYNC_FILE_RANGE_WAIT_AFTER	4

#endif
